package com.ikingtech.datav.service;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ikingtech.datav.enums.MediaFileTypeEnum;
import com.ikingtech.datav.enums.ProjectFileTypeEnum;
import com.ikingtech.datav.exception.ProjectFileExceptionInfo;
import com.ikingtech.datav.mapper.ProjectFileMapper;
import com.ikingtech.datav.model.entity.ProjectFileDO;
import com.ikingtech.datav.model.request.ProjectFileDTO;
import com.ikingtech.datav.model.request.ProjectFileSearchDTO;
import com.ikingtech.datav.model.result.ProjectFileVO;
import com.ikingtech.framework.sdk.base.model.PageResult;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.oss.model.OssFileDTO;
import com.ikingtech.framework.sdk.utils.Tools;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author fucb
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProjectFileService extends ServiceImpl<ProjectFileMapper, ProjectFileDO> {

    public PageResult<ProjectFileDO> selectByPage(ProjectFileSearchDTO queryParam) {
        LambdaQueryWrapper<ProjectFileDO> queryWrapper = Wrappers.<ProjectFileDO>lambdaQuery()
                .like(Tools.Str.isNotBlank(queryParam.getFileName()), ProjectFileDO::getFileName, queryParam.getFileName())
                .eq(Tools.Str.isNotBlank(queryParam.getId()), ProjectFileDO::getId, queryParam.getId())
                .eq(queryParam.getType() != null, ProjectFileDO::getType, queryParam.getType())
                .eq(ProjectFileDO::getProjectId, Tools.Str.is(queryParam.getProjectId()))
                .eq(Tools.Str.isNotBlank(queryParam.getUserId()), ProjectFileDO::getUserId, queryParam.getUserId());
        if (Tools.Str.isNotBlank(queryParam.getFileType())) {
            List<String> extensionsType;
            // 初始化一个内部的 OR 查询包装器 ， 其它类型排除所有获取
            if (MediaFileTypeEnum.OTHER.name().equals(queryParam.getFileType())) {
                extensionsType = MediaFileTypeEnum.getMediaType();
                extensionsType.forEach(e -> queryWrapper.notLikeLeft(ProjectFileDO::getFileName, e));
            } else {
                extensionsType = MediaFileTypeEnum.getExtensionsByType(queryParam.getFileType());
                queryWrapper.and(q-> {
                    LambdaQueryWrapper<ProjectFileDO> orWrapper = q.or();
                    extensionsType.forEach(e -> orWrapper.or().likeLeft(ProjectFileDO::getFileName, e));
                });
            }
        }
        queryWrapper.orderByDesc(ProjectFileDO::getCreateTime);
        return PageResult.build(this.page(new Page<>(queryParam.getPage(), queryParam.getRows()), queryWrapper));
    }

    public ProjectFileVO getInfo(String id) {
        ProjectFileDO entity = this.baseMapper.selectById(id);
        if (null == entity) {
            throw new FrameworkException(ProjectFileExceptionInfo.PROJECT_FILE_NOT_FOUND);
        }
        return Tools.Bean.copy(entity, ProjectFileVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    public ProjectFileDO add(ProjectFileDTO param) {
        ProjectFileDO projectFile = Tools.Bean.copy(param, ProjectFileDO.class);
        projectFile.setId(IdUtil.simpleUUID());
        this.baseMapper.insert(projectFile);
        return projectFile;
    }

    public void delete(String id) {
        this.baseMapper.deleteById(id);
    }

    public boolean exist(String id) {
        return this.baseMapper.exists(lambdaQuery().eq(ProjectFileDO::getId, id));
    }


    @Transactional(rollbackFor = Exception.class)
    public ProjectFileDTO upload(OssFileDTO data, ProjectFileTypeEnum type, String projectId) {
        ProjectFileDTO projectFile = new ProjectFileDTO();
        projectFile.setFileName(data.getOriginName());
        projectFile.setMixFileName(FileNameUtil.getName(data.getPath()));
        projectFile.setSize(data.getFileSize());
        projectFile.setType(type == null ? ProjectFileTypeEnum.COMMON : type);
        projectFile.setPath("/" + data.getPath());
        projectFile.setUserId(Me.id());
        projectFile.setUserName(Me.name());
        projectFile.setProjectId(ObjectUtil.defaultIfBlank(projectId, ""));
        add(projectFile);
        return projectFile;
    }
}
